package org.azj.dbOperatorComponent;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import javax.sql.DataSource;

import org.azj.logHelper.LOG;
import org.azj.logHelper.LOG_COMPONENT;
import org.azj.logHelper.LOG_LEVEL;


public abstract class DbQueryCommand implements ICommand
{
	@Override
	public List<HashMap<String, Object>> doCommand(DataSource ds) throws SQLException
	{
		Connection conn = SingleThreadConnectionHolder.getConnection(ds);
		PreparedStatement statement = null;
		try {
			statement = getStatement(conn);
		} catch (Exception e) {
			LOG.WriteLog(LOG_LEVEL.OPERATIONAL, LOG_COMPONENT.LOG_COMP_DB_CHANGE, "执行数据库任务时出现问题 : " + e.getMessage());
			throw new SQLException(e.getMessage());
		}
		ResultSet rs = statement.executeQuery();
		
		List<HashMap<String, Object>> resultList = new ArrayList<HashMap<String, Object>>();
		// 处理ResultSet
		
		// 处理每一行
		while (rs.next())
		{
			HashMap<String, Object> tmpHashMap = new HashMap<String, Object>();
			
			ResultSetMetaData metaData = rs.getMetaData();
			// 处理每一列
			int columnCount = metaData.getColumnCount();
			byte[] contents = null;
			for (int i = 1; i <= columnCount; i++)
			{
				// 下面的语句将会去掉所有的空格
				String columnName = String.format(
						"%s.%s.%s", 
						metaData.getSchemaName(i).replaceAll(" ","").toUpperCase(), 
						metaData.getTableName(i).replaceAll(" ","").toUpperCase(),
						metaData.getColumnName(i).replaceAll(" ","").toUpperCase());
				
				// 如果取出来的是二进制形式的数据，则应该进行转换
				if (metaData.getColumnTypeName(i).equals("BLOB") == true) 
				{
					Blob blob = (Blob) rs.getObject(i);
					contents = changeBlobTobytes(blob);
					if (contents == null) {
						throw new SQLException("BLOB数据转换至二进制数组错误，当前处理列[" + columnName + "]");
					}
					tmpHashMap.put(columnName, contents);
				}
				else
				{
					tmpHashMap.put(columnName, rs.getObject(i));
				}
			}
			
			resultList.add(tmpHashMap);
		}
		
		statement.close();
		
		return resultList; 	
	}	
	
	private byte[] changeBlobTobytes(Blob blob) {
		BufferedInputStream is = null;  
		  
		try {  
			is = new BufferedInputStream(blob.getBinaryStream());  
			byte[] bytes = new byte[(int) blob.length()];  
			int len = bytes.length;  
			int offset = 0;  
			int read = 0;  
			  
			while (offset < len && (read = is.read(bytes, offset, len - offset)) >= 0) {  
				offset += read;  
			}  
			return bytes;  
		} catch (Exception e) {  
			return null;  
		} finally {  
			try {  
				is.close();  
				is = null;  
			} catch (IOException e) {  
				return null;  
			}
		}
	}
}
